perm filename NETWRK.MID[NET,MRC]1 blob sn#314828 filedate 1977-11-04 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00013 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	Network routines, intended to be .INSRT'ed
C00007 00003	 Data area
C00009 00004	 CONECT -- Connect to foreign host
C00011 00005	 Now try to get to the foreign host's logger
C00013 00006	 Got socket number from logger
C00016 00007	 NETICH -- Read a character from the network
C00019 00008	 NETSND -- Force network buffer out
C00020 00009	 NETOCH -- Output a character to the network
C00021 00010	 CLOSER -- Close a connection
C00022 00011	 CHKCON -- Test status of connection
C00023 00012	 MTPERR -- Explain MTAPE lossage
C00025 00013	 NIOERR -- Explain network I/O lossage
C00027 ENDMK
C⊗;
SUBTTL Network routines, intended to be .INSRT'ed

;  This is a library of ARPAnet hacking routines.  Each routine describes its
; calling sequence and what AC's it smashes.  Only 0, 1, and 2 are ever used.
; A pushdown stack is expected in 17.  I/O channel 0 is smashed, and I/O channel
; 1 (NET) is used as the general network hacking channel.
; Bugs → MRC.

.BEGIN NETWRK

; Interrupt condition bits

.U"INITNR==000100,,			; IMP INR
.U"INITNS==000040,,			; IMP INS
.U"INITMS==000020,,			; IMP status change
.U"INITNP==000010,,			; IMP input waiting

; Network socket status flags

.U"RFCS==  200000,,			; RFC sent
.U"RFCR==  100000,,			; RFC received
.U"CLSS==  040000,,			; CLS sent
.U"CLSR==  020000,,			; CLS received
.U"INTINR==000100,,			; INR received
.U"INTINS==000040,,			; INS received

; Network I/O status bits

.U"HDEAD== 002000			; host or destination IMP dead
.U"CTROV== 001000			; host sent more bits than allocated
.U"RSET==  000400			; host sent a RST
.U"TMO==   000200			; time out

; Network status word error codes

.U"SUI==01				; socket in use
.U"CCS==02				; can't change socket numbers
.U"SYS==03				; horrible system error
.U"NLA==04				; no links available
.U"ILB==05				; illegal byte size
.U"IDD==06				; IMP dead

; I/O status word error bits

.U"IOIMPM==400000			; improper mode
.U"IODERR==200000			; hard device error
.U"IODTER==100000			; soft device error
.U"IOBKTL==040000			; block number out of bounds
.U"IODEND==020000			; end of file

ERRBTS==IOIMPM\IODERR\IODTER\IOBKTL\IODEND\HDEAD\CTROV\RSET\TMO ; all I/O lossage
WINBTS==RFCS\RFCR			; connection winning

; Assembly switches

IFNDEF PADPRC,PADPRC==0			; ≠ 0 → padding nulls are converted to
					;  PADCHR.  = 0 → all nulls and rubouts
					;  are flushed
IFNDEF PADCHR,PADCHR==241		; default padding character (TELNET NOP)

; I/O channel definitions

ICP==0					; channel to get socket from logger
.U"NET==1				; channel to do real network hacking
; Data area

; CONNECT MTAPE block

CONBLK:	0				; CONNECT
CONSTS:	BLOCK 1				; returned status bits
CONLSK:	BLOCK 1				; local socket
CONWAT:	BLOCK 1				; ≠ 0 → wait for connection until timeout
CONBYT:	BLOCK 1				; byte size
.U"ICPSKT:
	BLOCK 1				; foreign socket
.U"HOST:
	BLOCK 1				; foreign host

; STATUS MTAPE block

STABLK:	2				; STATUS
STALSS:	BLOCK 1				; status of local send side
STALRS:	BLOCK 1				; status of local receive side

; CLOSE MTAPE block

CLSBLK:	3				; CLOSE
CLSSTS:	BLOCK 1				; returned status bits
CLSSKT:	BLOCK 1				; socket number
CLSWAT:	BLOCK 1				; ≠ 0 → wait

; WAIT MTAPE block

WATBLK:	4				; WAIT
WATSTS:	BLOCK 1				; returned status bits
WATSKT:	BLOCK 1				; socket number

; I/O buffer headers

NTIBF:	BLOCK 3				; network input buffer header
NTOBF:	BLOCK 3				; network output buffer header
; CONECT -- Connect to foreign host
; Call:	MOVEM <host number>,HOST
;	MOVEM <ICP socket number>,ICPSKT
;	PUSHJ 17,CONECT
;	<error return--MTAPE lossage, status in 0>
;	<error return--I/O error, status in 0>
;	<return>
; Smashes 0 and 1.

; Open channels and set timeouts

.U"CONECT:
	INIT ICP,17			; open ICP in dump mode
		SIXBIT/IMP/		; device IMP:
		0			; no buffers
	 JRST [	OUTSTR [ASCIZ/Unable to INIT the IMP.
Find a wizard.
/]
		JRST 4,.-1]
	MTAPE ICP,[	17		; set timeouts
			.BYTE 6 ? 2 ? 24 ? 0 ? 7 ? 7 ? 0]
	INIT NET,0			; open NET in ASCII mode
		SIXBIT/IMP/
		NTOBF,,NTIBF		; buffers
	 JRST [	OUTSTR [ASCIZ/Unable to INIT the IMP.
Find a wizard.
/]
		JRST 4,.-1]
	MTAPE NET,[	17		; set timeouts
			.BYTE 6 ? 2 ? 24 ? 0 ? 7 ? 0 ? 0]

;  Try to generate a unique socket number, using job number and
; time of day to avoid lossage due to old connections.
; Algorithm used is: job #,,<time&777770>

	PJOB				; get my job #
	MSTIME 1,			; and the time now
	LSH 18.				; put job # in LH
	HRRI (1)			; and time in RH
	TRZ 7				; but zap low order bits
; Falls through
; Now try to get to the foreign host's logger

	MOVEM CONLSK			; my socket to use
	MOVEM CLSSKT			; socket to close when done
	SETOM CONWAT			; do wait until timeout
	MTAPE ICP,CONBLK		; connect → foreign logger
	MOVE CONSTS			; check for MTAPE error
	TRNE 77
	 POPJ 17,
	MOVE 1,
	GETSTS ICP,			; check for I/O error
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE 1
	TLC WINBTS			; for next instruction to win
	TLCE WINBTS			; legal socket state?
	 POPJ 17,
	HRROI ICPSKT-1			; get ready to get a socket
	SETZ 1,				; stop code for dump mode

; Get socket number from logger

	IN ICP,				; get socket from logger
	 JRST GOTSKT			; won
	GETSTS ICP,
	JRST CPOPJ1

GOTSKT:	LDB [044000,,ICPSKT]		; get socket we got
	MOVEM ICPSKT			; and save it back
	MTAPE ICP,CLSBLK		; close off ICP socket
	RELEAS ICP,			; free up channel
; Falls through
; Got socket number from logger

; Now connect output

	MOVEI 3				; ICP/transmit offset
	ADDB CONLSK			; local transmit socket
	MOVEM WATSKT			; save wait socket
	SETZM CONWAT			; don't wait
	MOVEI 8.			; 8 bit bytes
	MOVEM CONBYT
	MTAPE NET,CONBLK		; connect → server output
	MOVE CONSTS			; test for error
	TRNE 77
	 POPJ 17,

; Now connect input

	SOS CONLSK			; local receive socket
	AOS ICPSKT			; foreign transmit socket
	MTAPE NET,CONBLK		; connect ← server input
	MOVE CONSTS			; test for error
	TRNE 77
	 POPJ 17,

; Connections started, now wait for output

	MTAPE NET,WATBLK		; wait for output
	MOVE WATSTS			; get status
	TRNE 77
	 POPJ 17,
	MOVE 1,
	GETSTS NET,
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE 1
	TLC WINBTS
	TLCE WINBTS
	 POPJ 17,

; Output connected, now wait for input

	SOS WATSKT			; now select receive socket
	MTAPE NET,WATBLK		; wait for input
	MOVE WATSTS			; get status
	TRNE 77
	 POPJ 17,
	MOVE 1,
	GETSTS NET,
	TRNE ERRBTS
	 JRST CPOPJ1
	MOVE 1
	TLC WINBTS
	TLCE WINBTS
	 POPJ 17,

; Set up allocations, buffer headers, and return.

	MTAPE NET,[15 ? 1]		; system maximum allocation
	MOVEI 8.			; change byte size in buffer header
	DPB [300600,,NTIBF+1]
	DPB [300600,,NTOBF+1]

; Return routines

.U"CPOPJ2:
	AOS (17)			; double skip return
.U"CPOPJ1:
	AOS (17)			; skip return
.U"CPOPJ:
	POPJ 17,			; return to caller
; NETICH -- Read a character from the network
; NETICW -- Read a character from the network, hang for it
; Call:	PUSHJ 17,NETICH
;	<error return--no characters available>
;	<error return--I/O error, status in 0>
;	<success--character in 0>
; Smashes 0, 1, and 2.

.U"NETICH:
	TDZA 2,2			; don't hang
.U"NETICW:
	 SETO 2,			; hang
NTICH2:	SOSG NTIBF+2			; anything in buffer?
	 JRST [	MTAPE NET,[10]		; no, any input available?
		 JUMPE 2,[POPJ 17,]	; no, error return
		IN NET,			; yes, read the buffer
		 JRST .+1		; won
		GETSTS NET,		; error, get status
		JRST CPOPJ1]		; I/O error return
IFN PADPRC,[	; If processing padding nulls
	IBP NTIBF+1			; point to byte to hack
	MOVE @NTIBF+1			; get the word of that byte
	ANDI 17				; only marking bits
	JFFO .+2			; count leading zeros
	 JRST NTICH1			; no padding bytes
	ANDCAM @NTIBF+1			; turn off mark bits
	MOVE -32(1)+[	.BYTE 8 ? PADCHR ? PADCHR ? PADCHR ? PADCHR
			.BYTE 8 ? 0 ? PADCHR ? PADCHR ? PADCHR
			.BYTE 8 ? 0 ? 0 ? PADCHR ? PADCHR
			.BYTE 8 ? 0 ? 0 ? 0 ? PADCHR]
	IORM @NTIBF+1			; convert padding nulls to no-op character
NTICH1:	LDB NTIBF+1			; get the character
	CAIN PADCHR			; padding character?
	 JRST NTICH2			; yes, start over
]; END IFN PADPRC

IFE PADPRC,[	; If ignoring nulls and rubouts
	ILDB NTIBF+1			; get the character
	JUMPE NTICH2			; flush nulls
	CAIN 177			; and rubouts
	 JRST NTICH2
]; END IFE PADPRC
	JRST CPOPJ2			; won
; NETSND -- Force network buffer out
; Call:	PUSHJ 17,NETSND
;	<error return--I/O error, status in 0>
;	<return>
; Smashes 0 and 1.

.U"NETSND:
	LDB 1,[410300,,NTOBF+1]		; get position field
	MOVEI 1
	LSH (1)				; AC0 ← 2↑<# of null characters>
	SOS				; AC0 ← mask to flush nulls
	IORM @NTOBF+1			; ensure padding nulls aren't sent
	OUT NET,			; send the buffer
	 JRST CPOPJ1			; success
NETOER:	GETSTS NET,			; lost, get status
	POPJ 17,			; and return
; NETOCH -- Output a character to the network
; Call:	MOVE <character>
;	PUSHJ 17,NETOCH
;	<error return--I/O error, status in 0>
;	<return>
; Smashes 0.

.U"NETOCH:
	SOSG NTOBF+2			; space available in buffer?
	 OUT NET,			; no, output it
	  CAIA				; win
	   JRST NETOER
	IDPB NTOBF+1			; put character in buffer
	JRST CPOPJ1			; success
; CLOSER -- Close a connection
; Call:	PUSHJ 17,CLOSER
;	<return>
; Smashes 0.

.U"CLOSER:
	MOVEI 2				; receive socket offset
	ADDM CLSSKT
	MTAPE NET,CLSBLK		; close receive socket
	AOS CLSSKT			; send socket offset
	MTAPE NET,CLSBLK		; close send socket
	POPJ 17,
; CHKCON -- Test status of connection
; Call:	PUSHJ 17,CHKCON
;	<error return--MTAPE lossage, status in 0>
;	<error return--I/O error, status in 0>
;	<return>
; Smashes 0.

.U"CHKCON:
	GETSTS NET,			; check for I/O error
	TRNE ERRBTS
	 JRST CPOPJ1
	MTAPE NET,STABLK		; get connection status
	MOVE STALSS			; check send side
	TRNE 77
	 POPJ 17,
	TLC WINBTS			; for next instruction to win
	TLCE WINBTS			; legal socket state?
	 POPJ 17,
	MOVE STALRS			; check receive side
	TRNE 77
	 POPJ 17,
	TLC WINBTS			; for next instruction to win
	TLCE WINBTS			; legal socket state?
	 POPJ 17,
	JRST CPOPJ2
; MTPERR -- Explain MTAPE lossage
; Call:	MOVE <MTAPE status bits>
;	PUSHJ 17,MTPERR
;	<return>
; Smashes 0.

.U"MTPERR:
	TRNE 77				; UUO lossage?
	 JRST MTPER1			; yes, different message
	TLNN CLSR			; closed by foreign host?
	 JRST [	MOVEI TMO		; no, fake a time out
		JRST NIOERR]
	OUTSTR [ASCIZ/Host closed connection
/]
	POPJ 17,

; MTAPE UUO lossage

MTPER1:	ANDI 77				; only error code
	OUTSTR [ASCIZ/MTAPE UUO error -- /]
	CAILE MERLEN			; error code too high?
	 JRST [	OUTCHR ["#]
		IDIVI 10
		ADDI "0
		ADDI 1,"0
		OUTCHR
		OUTCHR 1
		JRST MTPE1A]
	MOVE 1,
	OUTSTR @MERTAB-1(1)		; output the error string
MTPE1A:	OUTSTR [ASCIZ/
Find a wizard.
/]
	POPJ 17,

MERTAB:	[ASCIZ/Socket already in use./]
	[ASCIZ/Can't change socket numbers./]
	[ASCIZ/Horrible system error./]
	[ASCIZ/No links available./]
	[ASCIZ/Illegal byte size./]
	[ASCIZ/Our NCP is dead./]
MERLEN==.-MERTAB
; NIOERR -- Explain network I/O lossage
; Call:	MOVE <I/O status bits>
;	PUSHJ 17,NIOERR
;	<return>
; Smashes 0.

.U"NIOERR:
	ANDI ERRBTS			; only error bits
	OUTSTR [ASCIZ/Connection failed -- /]
	TRNE HDEAD
	 OUTSTR [ASCIZ/Host dead.
/]
	TRNE CTROV
	 OUTSTR [ASCIZ/Host exceeded allocation.
/]
	TRNE RSET
	 OUTSTR [ASCIZ/Host RESET.
/]
	TRNE TMO
	 OUTSTR [ASCIZ/Time out.
/]
	TRNE IOIMPM\IOBKTL
	 OUTSTR [ASCIZ/IOIMPM or IOBKTL!
Find a wizard.
/]
	TRNE IODEND
	 OUTSTR [ASCIZ/End of file.
/]
	TRZE IODERR
	 TRO IODTER
	CAIN IODERR
	 OUTSTR [ASCIZ/Incomplete transmission.
/]
	POPJ 17,

.END NETWRK